public void RecompressData(){
//Chrono Trigger Recompression Routine
//Reverse engineered by Michael Springer (evilpeer@hotmail.com)
ushort j;
ushort k;
byte i;
byte nBitCtr; // Bit counter used for construction of Packet Header
ushort nOffset; // Byte offset in uncompressed data of pattern (counting backwards from current position)
ushort nCopyLength; // Number of bytes to copy when uncompressing
uint nSrcPos; // Byte position in uncompressed (source) data
ushort nWorkPos; // Byte position in compressed data
ushort nPackHdrOff; // Packet Header, constructed as source data is read
byte[][] CompData = new byte[2][];
ushort nCompSize = 0xFFFF;
ushort nArrLength = 0; // Final data length
ushort nRange; // The maximum range is either 0x0FFF or 0x07FF
byte nMaxCopy; // The maximum number of bytes to copy is either 18 or 34
// External class variables, set by calling function. May or may not be used
// uint nSrcOff; // Source starting offset
// uint nWorkOff; // Destination array starting offset
// uint nCompressedSize;
// uint nDecompressedSize;
// byte[] WorkingBuffer; // Destination array
// byte[] SrcBuffer; // Source array
for(i = 0; i < 2; i++){
nRange = (ushort) (0x07FF | (i << 11));
nMaxCopy = (byte) (18 + ((1 - i) << 4));
nSrcPos = 1;
nBitCtr = 1;
nOffset = 0;
nCopyLength = 0;
nWorkPos = 4;
nPackHdrOff = 2;
CompData[i] = new byte[0x10000];
CompData[i][3] = SrcBuffer[nSrcOff];
while(nSrcPos < nDecompressedSize && nWorkPos < nCompSize){
for(; nBitCtr < 8 && nSrcPos < nDecompressedSize; nBitCtr++){
if(nSrcPos > nRange){
j = (ushort) (nSrcPos - nRange);
}
else{
j = 0;
}
for(; j < nSrcPos; j++){
for(k = 0; k < nMaxCopy && SrcBuffer[nSrcOff + j + k] == SrcBuffer[nSrcOff + nSrcPos + k]; k++){
}
if(k >= nCopyLength){
nOffset = j;
nCopyLength = k;
if(k == nMaxCopy){
break;
}
}
}
if(nCopyLength > 2){
CompData[i][nPackHdrOff] |= (byte) (1 << nBitCtr);
nOffset = (ushort) (nSrcPos - nOffset);
CompData[i][nWorkPos++] = (byte) (nOffset & 0xFF);
CompData[i][nWorkPos++] = (byte) (((nCopyLength - 3) << (3 + i)) | ((nOffset >> 8) & (0x07 | (i << 3))));
nSrcPos += nCopyLength;
nCopyLength = 0;
}
else{
CompData[i][nWorkPos++] = SrcBuffer[nSrcOff + nSrcPos++];
}
}
if(nBitCtr == 8){
nBitCtr = 0;
nPackHdrOff = nWorkPos;
nWorkPos++;
}
}
if(nWorkPos < nCompSize){
if(nBitCtr > 0){
CompData[i][nPackHdrOff] |= (byte) (0xFF << nBitCtr);
Array.Copy(CompData[i], nPackHdrOff, CompData[i], nPackHdrOff + 3, nWorkPos - nPackHdrOff);
CompData[i][nPackHdrOff] = (byte) (nBitCtr | (0xC0 * (i - 1)));
nArrLength = (ushort) (nWorkPos + 3);
CompData[i][nPackHdrOff + 1] = (byte) nArrLength;
CompData[i][nPackHdrOff + 2] = (byte) (nArrLength >> 8);
CompData[i][nWorkPos + 3] = 0;
}
else{
nArrLength = (ushort) (nPackHdrOff + 1);
CompData[i][nPackHdrOff] = (byte) (0xC0 * (i - 1));
}
nCompSize = (ushort) (nPackHdrOff - 2);
CompData[i][0] = (byte) (nCompSize & 0xFF);
CompData[i][1] = (byte) (nCompSize >> 8);
Array.Copy(CompData[i], 0, WorkingBuffer, nWorkOff, nArrLength + 1);
nCompressedSize = (uint) (nArrLength + 1);
}
}
}
}